﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Spring.Transaction.Interceptor;

using BOSS.Domain;
using BOSS.Dao;
using BOSS.Framework.Search;
using BOSS.Framework.Search.Context;

namespace BOSS.Service.Implements
{
    /// <summary>
    /// 实体服务抽象基类
    /// </summary>
    /// <typeparam name="T">实体类型</typeparam>
    /// <typeparam name="IdT">Id 类型</typeparam>
    /// <typeparam name="U">实体 DAO 类型</typeparam>
    public abstract class EntityService<T, IdT, U> : IEntityService<T, IdT>, ISearchSupport<T>
        where T : IEntity<IdT>
        where U : IEntityDao<T, IdT>
    {
        /// <summary>
        /// 获取 / 设置 实体 DAO
        /// </summary>
        public U EntityDao { get; set; }

        #region IEntityService<T, IdT> Members

        /// <summary>
        /// 根据实体 ID 查找实体。找不到则返回 null
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public virtual T FindById(IdT id)
        {
            return this.EntityDao.FindById(id);
        }

        /// <summary>
        /// 查询所有的实体
        /// </summary>
        /// <returns></returns>
        public virtual IList<T> SelectAll()
        {
            return this.EntityDao.SelectAll();
        }

        /// <summary>
        /// 保存实体
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        [Transaction(ReadOnly = false)]
        public virtual IdT Save(T entity)
        {
            return this.EntityDao.Save(entity);
        }

        /// <summary>
        /// 更新实体
        /// </summary>
        /// <param name="entity"></param>
        [Transaction(ReadOnly = false)]
        public virtual void Update(T entity)
        {
            this.EntityDao.Update(entity);
        }

        /// <summary>
        /// 保存或更新实体
        /// </summary>
        /// <param name="entity"></param>
        [Transaction(ReadOnly = false)]
        public virtual void SaveOrUpdate(T entity)
        {
            this.EntityDao.SaveOrUpdate(entity);
        }

        /// <summary>
        /// 删除实体
        /// </summary>
        /// <param name="entity"></param>
        [Transaction(ReadOnly = false)]
        public virtual void Delete(T entity)
        {
            this.EntityDao.Delete(entity);
        }

        /// <summary>
        /// 刷新实体（即从数据库中重新获取相应值）
        /// </summary>
        /// <param name="entity"></param>
        public virtual void Refresh(T entity)
        {
            this.EntityDao.Refresh(entity);
        }

        /// <summary>
        /// 将实体从会话缓存中移除
        /// </summary>
        /// <param name="entity"></param>
        public virtual void Evict(T entity)
        {
            this.EntityDao.Evict(entity);
        }

        /// <summary>
        /// 将当前挂起的各项操作（save、update、delete）刷新到数据库中
        /// </summary>
        public virtual void FlushSession()
        {
            this.EntityDao.Flush();
        }

        /// <summary>
        /// 清除当前会话缓存中的所有数据，取消挂起的各项操作（save、update、delete）
        /// </summary>
        public virtual void ClearSession()
        {
            this.EntityDao.Clear();
        }

        #endregion

        #region ISearchSupport<T> 成员

        /// <summary>
        /// 根据搜索上下文查找内容
        /// </summary>
        /// <param name="context"></param>
        /// <param name="totalCount"></param>
        /// <returns></returns>
        public IList<T> SelectBySearch(ISearchContext context, out int totalCount)
        {
            ISearchSupport<T> dao = this.EntityDao as ISearchSupport<T>;
            if (dao == null)
            {
                throw new NotSupportedException(string.Format("{0} 不支持搜索，需要先实现 ISearchSupport<{1}> 接口",
                    this.EntityDao.GetType().Name, typeof(T).Name));
            }
            return dao.SelectBySearch(context, out totalCount);
        }

        #endregion
    }
}
